jetcrab\vm\types/
addresses.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub struct CodeAddress(usize);
6
7impl CodeAddress {
8    pub fn new(address: usize) -> Self {
9        Self(address)
10    }
11
12    pub fn as_usize(&self) -> usize {
13        self.0
14    }
15
16    pub fn increment(&mut self) {
17        self.0 += 1;
18    }
19
20    pub fn add(&self, offset: usize) -> Self {
21        Self(self.0 + offset)
22    }
23}
24
25impl From<usize> for CodeAddress {
26    fn from(address: usize) -> Self {
27        Self(address)
28    }
29}
30
31impl From<CodeAddress> for usize {
32    fn from(addr: CodeAddress) -> Self {
33        addr.0
34    }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
38pub struct LineNumber(usize);
39
40impl LineNumber {
41    pub fn new(line: usize) -> Self {
42        Self(line)
43    }
44
45    pub fn as_usize(&self) -> usize {
46        self.0
47    }
48
49    pub fn is_valid(&self) -> bool {
50        self.0 > 0
51    }
52}
53
54impl From<usize> for LineNumber {
55    fn from(line: usize) -> Self {
56        Self(line)
57    }
58}
59
60impl From<LineNumber> for usize {
61    fn from(line: LineNumber) -> Self {
62        line.0
63    }
64}
65
66impl fmt::Display for LineNumber {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        write!(f, "{}", self.0)
69    }
70}
71
72impl std::ops::AddAssign<usize> for LineNumber {
73    fn add_assign(&mut self, rhs: usize) {
74        self.0 += rhs;
75    }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
79pub struct ColumnNumber(usize);
80
81impl ColumnNumber {
82    pub fn new(column: usize) -> Self {
83        Self(column)
84    }
85
86    pub fn as_usize(&self) -> usize {
87        self.0
88    }
89
90    pub fn is_valid(&self) -> bool {
91        self.0 > 0
92    }
93}
94
95impl From<usize> for ColumnNumber {
96    fn from(column: usize) -> Self {
97        Self(column)
98    }
99}
100
101impl From<ColumnNumber> for usize {
102    fn from(col: ColumnNumber) -> Self {
103        col.0
104    }
105}
106
107impl fmt::Display for ColumnNumber {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        write!(f, "{}", self.0)
110    }
111}
112
113impl std::ops::AddAssign<usize> for ColumnNumber {
114    fn add_assign(&mut self, rhs: usize) {
115        self.0 += rhs;
116    }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
120pub struct SourcePosition {
121    pub line: LineNumber,
122    pub column: ColumnNumber,
123}
124
125impl SourcePosition {
126    pub fn new(line: usize, column: usize) -> Self {
127        Self {
128            line: LineNumber::new(line),
129            column: ColumnNumber::new(column),
130        }
131    }
132
133    pub fn as_tuple(&self) -> (usize, usize) {
134        (self.line.as_usize(), self.column.as_usize())
135    }
136}
137
138impl From<(usize, usize)> for SourcePosition {
139    fn from((line, column): (usize, usize)) -> Self {
140        Self::new(line, column)
141    }
142}
143
144impl fmt::Display for SourcePosition {
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        write!(f, "{}:{}", self.line, self.column)
147    }
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
151pub struct CharOffset(usize);
152
153impl CharOffset {
154    pub fn new(offset: usize) -> Self {
155        Self(offset)
156    }
157
158    pub fn as_usize(&self) -> usize {
159        self.0
160    }
161
162    pub fn is_zero(&self) -> bool {
163        self.0 == 0
164    }
165
166    pub fn is_positive(&self) -> bool {
167        self.0 > 0
168    }
169
170    pub fn increment(&mut self) {
171        self.0 += 1;
172    }
173
174    pub fn decrement(&mut self) {
175        if self.0 > 0 {
176            self.0 -= 1;
177        }
178    }
179
180    pub fn add(&self, other: usize) -> Self {
181        Self(self.0 + other)
182    }
183
184    pub fn sub(&self, other: usize) -> Self {
185        Self(self.0.saturating_sub(other))
186    }
187}
188
189impl From<usize> for CharOffset {
190    fn from(offset: usize) -> Self {
191        Self(offset)
192    }
193}
194
195impl From<CharOffset> for usize {
196    fn from(offset: CharOffset) -> Self {
197        offset.0
198    }
199}
200
201impl std::ops::Add<usize> for CharOffset {
202    type Output = Self;
203
204    fn add(self, other: usize) -> Self {
205        Self(self.0 + other)
206    }
207}
208
209impl std::ops::Sub<usize> for CharOffset {
210    type Output = Self;
211
212    fn sub(self, other: usize) -> Self {
213        Self(self.0.saturating_sub(other))
214    }
215}
216
217impl std::ops::AddAssign<usize> for CharOffset {
218    fn add_assign(&mut self, rhs: usize) {
219        self.0 += rhs;
220    }
221}
222
223impl std::ops::SubAssign<usize> for CharOffset {
224    fn sub_assign(&mut self, rhs: usize) {
225        self.0 = self.0.saturating_sub(rhs);
226    }
227}
228
229impl fmt::Display for CharOffset {
230    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231        write!(f, "{}", self.0)
232    }
233}